const AuthService = require('../services/AuthService');
const User = require('../models/User');
const { BadRequestError, UnauthorizedError, ForbiddenError } = require('../utils/errors');
const passwordUtils = require('../utils/password');

/**
 * 认证控制器
 * 处理用户认证相关的HTTP请求
 */
class AuthController {
  /**
   * 用户登录
   * @param {Object} req - Express请求对象
   * @param {Object} res - Express响应对象
   * @param {Function} next - Express下一个中间件
   */
  static async login(req, res, next) {
    try {
      const { username, email, password } = req.body;

      // 验证输入
      if (!password) {
        throw new BadRequestError('密码不能为空');
      }

      // 用户名或邮箱至少提供一个
      const loginIdentifier = username || email;
      if (!loginIdentifier) {
        throw new BadRequestError('请提供用户名或邮箱');
      }

      // 调用认证服务进行登录
      const result = await AuthService.login(loginIdentifier, password);

      // 记录登录日志（这里可以扩展为更详细的日志记录）
      console.log(`用户 ${result.user.username} 登录成功`);

      // 返回成功响应
      res.status(200).json({
        success: true,
        message: '登录成功',
        data: result
      });
    } catch (error) {
      next(error);
    }
  }

  /**
   * 用户注册
   * @param {Object} req - Express请求对象
   * @param {Object} res - Express响应对象
   * @param {Function} next - Express下一个中间件
   */
  static async register(req, res, next) {
    try {
      const { username, email, password, confirmPassword, nickname, avatar } = req.body;

      // 验证输入
      if (!username || !email || !password) {
        throw new BadRequestError('用户名、邮箱和密码不能为空');
      }

      // 确认密码
      if (password !== confirmPassword) {
        throw new BadRequestError('两次输入的密码不一致');
      }

      // 检查密码强度
      const passwordStrength = passwordUtils.checkPasswordStrength(password);
      if (passwordStrength.strength <= 1) {
        throw new BadRequestError(`密码强度不足: ${passwordStrength.message}`, {
          suggestions: passwordStrength.suggestions
        });
      }

      // 调用认证服务进行注册
      const result = await AuthService.register({
        username,
        email,
        password,
        nickname,
        avatar
      });

      // 记录注册日志
      console.log(`新用户 ${result.user.username} 注册成功`);

      // 返回成功响应
      res.status(201).json({
        success: true,
        message: '注册成功',
        data: result
      });
    } catch (error) {
      next(error);
    }
  }

  /**
   * 刷新令牌
   * @param {Object} req - Express请求对象
   * @param {Object} res - Express响应对象
   * @param {Function} next - Express下一个中间件
   */
  static async refreshToken(req, res, next) {
    try {
      const { refreshToken } = req.body;

      if (!refreshToken) {
        throw new BadRequestError('刷新令牌不能为空');
      }

      // 调用认证服务刷新令牌
      const newTokens = await AuthService.refreshTokens(refreshToken);

      // 返回新令牌
      res.status(200).json({
        success: true,
        message: '令牌刷新成功',
        data: {
          tokens: newTokens
        }
      });
    } catch (error) {
      next(error);
    }
  }

  /**
   * 用户登出
   * @param {Object} req - Express请求对象
   * @param {Object} res - Express响应对象
   * @param {Function} next - Express下一个中间件
   */
  static async logout(req, res, next) {
    try {
      // 在实际项目中，这里可以将令牌加入黑名单或进行其他处理
      // 目前仅返回成功响应
      res.status(200).json({
        success: true,
        message: '登出成功'
      });
    } catch (error) {
      next(error);
    }
  }

  /**
   * 请求重置密码
   * @param {Object} req - Express请求对象
   * @param {Object} res - Express响应对象
   * @param {Function} next - Express下一个中间件
   */
  static async requestPasswordReset(req, res, next) {
    try {
      const { email } = req.body;
      
      if (!email) {
        throw new BadRequestError('邮箱不能为空');
      }
      
      // 调用认证服务请求重置密码
      await AuthService.requestPasswordReset(email);
      
      res.status(200).json({
        success: true,
        message: '密码重置链接已发送到您的邮箱'
      });
    } catch (error) {
      next(error);
    }
  }

  /**
   * 重置密码
   * @param {Object} req - Express请求对象
   * @param {Object} res - Express响应对象
   * @param {Function} next - Express下一个中间件
   */
  static async resetPassword(req, res, next) {
    try {
      const { token, newPassword, confirmNewPassword } = req.body;
      
      if (!token || !newPassword || !confirmNewPassword) {
        throw new BadRequestError('请提供重置令牌和新密码');
      }
      
      if (newPassword !== confirmNewPassword) {
        throw new BadRequestError('两次输入的新密码不一致');
      }
      
      // 调用认证服务重置密码
      await AuthService.resetPassword(token, newPassword);
      
      res.status(200).json({
        success: true,
        message: '密码重置成功'
      });
    } catch (error) {
      next(error);
    }
  }

  /**
   * 获取当前用户信息
   * @param {Object} req - Express请求对象
   * @param {Object} res - Express响应对象
   * @param {Function} next - Express下一个中间件
   */
  static async getCurrentUser(req, res, next) {
    try {
      // 从请求对象中获取用户信息（由认证中间件设置）
      const user = req.user;

      if (!user) {
        throw new UnauthorizedError('用户未认证');
      }

      // 获取完整用户信息
      const fullUser = await User.findByPk(user.id, {
        attributes: {
          exclude: ['password', 'loginAttempts', 'lockUntil', 'deletedAt']
        }
      });

      if (!fullUser) {
        throw new UnauthorizedError('用户不存在');
      }

      // 返回用户信息
      res.status(200).json({
        success: true,
        message: '获取用户信息成功',
        data: {
          user: fullUser.toJSON()
        }
      });
    } catch (error) {
      next(error);
    }
  }

  /**
   * 修改密码
   * @param {Object} req - Express请求对象
   * @param {Object} res - Express响应对象
   * @param {Function} next - Express下一个中间件
   */
  static async changePassword(req, res, next) {
    try {
      const { oldPassword, newPassword, confirmNewPassword } = req.body;
      const userId = req.user.id;

      // 验证输入
      if (!oldPassword || !newPassword || !confirmNewPassword) {
        throw new BadRequestError('请填写所有密码字段');
      }

      // 确认新密码
      if (newPassword !== confirmNewPassword) {
        throw new BadRequestError('两次输入的新密码不一致');
      }

      // 检查新密码强度
      const passwordStrength = passwordUtils.checkPasswordStrength(newPassword);
      if (passwordStrength.strength <= 1) {
        throw new BadRequestError(`新密码强度不足: ${passwordStrength.message}`, {
          suggestions: passwordStrength.suggestions
        });
      }

      // 查找用户
      const user = await User.findByPk(userId);
      if (!user) {
        throw new UnauthorizedError('用户不存在');
      }

      // 验证旧密码
      if (!user.verifyPassword(oldPassword)) {
        throw new BadRequestError('旧密码错误');
      }

      // 更新密码
      user.password = newPassword;
      await user.save();

      // 记录密码修改日志
      console.log(`用户 ${user.username} 修改密码成功`);

      // 返回成功响应
      res.status(200).json({
        success: true,
        message: '密码修改成功'
      });
    } catch (error) {
      next(error);
    }
  }

  /**
   * 更新用户信息
   * @param {Object} req - Express请求对象
   * @param {Object} res - Express响应对象
   * @param {Function} next - Express下一个中间件
   */
  static async updateProfile(req, res, next) {
    try {
      const { nickname, avatar, phone } = req.body;
      const userId = req.user.id;

      // 查找用户
      const user = await User.findByPk(userId);
      if (!user) {
        throw new UnauthorizedError('用户不存在');
      }

      // 更新用户信息
      const updateData = {};
      if (nickname !== undefined) updateData.nickname = nickname;
      if (avatar !== undefined) updateData.avatar = avatar;
      if (phone !== undefined) updateData.phone = phone;

      await user.update(updateData);

      // 返回更新后的用户信息
      const updatedUser = await User.findByPk(userId, {
        attributes: {
          exclude: ['password', 'loginAttempts', 'lockUntil', 'deletedAt']
        }
      });

      res.status(200).json({
        success: true,
        message: '个人信息更新成功',
        data: {
          user: updatedUser.toJSON()
        }
      });
    } catch (error) {
      next(error);
    }
  }
}

module.exports = AuthController;

// 导出到全局
global.AuthController = AuthController;